package common.activiti.web.action;

import java.util.List;

import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.form.TaskFormData;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.activiti.engine.task.Attachment;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.IdentityLinkType;
import org.activiti.engine.task.NativeTaskQuery;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;

import common.hibernate.vo.Page;
import common.security.web.util.SecurityUtil;
import common.web.action.CommonAction;
import common.web.vo.Result;

/**
 * 运行中的执行实例Execution
 */
@RestController
@RequestMapping("/bpm/task")
public class TaskController extends CommonAction {

	@Autowired
	RuntimeService runtimeService;

	@Autowired
	RepositoryService repositoryService;

	@Autowired
	TaskService taskService;

	@Autowired
	IdentityService identityService;

	@Autowired
	FormService formService;

	@Autowired
	HistoryService historyService;

	/**
	 * 读取启动流程的表单字段
	 */
	@RequestMapping(value = "list")
	public Result todoTasks(@RequestBody JSONObject json) throws Exception {

		String taskName = json.getString("taskName");
		Page<Task> page = new Page<Task>();
		page.setPageSize(super.getPageSize(json));
		page.setCurrentPage(super.getPageNumber(json));
		String userId = SecurityUtil.getUserId();

		NativeTaskQuery nativeTaskQuery = taskService.createNativeTaskQuery();

		/*
		 * 过滤条件
		 */
		String filters = "";
		if (StringUtils.isNotBlank(taskName)) {
			filters += " and RES.NAME_ like #{taskName}";
			nativeTaskQuery.parameter("taskName", "%" + taskName + "%");
		}

		// 当前人在候选人或者候选组范围之内
		String sql = "select distinct RES.* from ACT_RU_TASK RES left join ACT_RU_IDENTITYLINK I on I.TASK_ID_ = RES.ID_ WHERE SUSPENSION_STATE_ = '1' and "
				+ " ( RES.ASSIGNEE_ = #{userId}"
				+ " or (RES.ASSIGNEE_ is null  and ( I.USER_ID_ = #{userId} or I.GROUP_ID_ IN (select G.GROUP_ID_ from ACT_ID_MEMBERSHIP G where G.USER_ID_ = #{userId} ) )"
				+ ") )" + filters + " order by RES.CREATE_TIME_ desc";

		nativeTaskQuery.sql(sql).parameter("userId", userId);
		List<Task> tasks = nativeTaskQuery.listPage(page.getStart(), page.getPageSize());

		page.setRows(tasks);
		page.setTotal(Long.valueOf(nativeTaskQuery.sql("select count(*) from (" + sql + ") t").count()).intValue());

		// 从5.16版本开始可以使用以下方式
		/*
		 * TaskQuery taskQuery =
		 * taskService.createTaskQuery().taskCandidateOrAssigned(user.getId());
		 * page.setTotalCount(taskQuery.count());
		 * page.setResult(taskQuery.list()); mav.addObject("tasks", tasks);
		 */

		return Result.createPageResult(page);
	}

	/**
	 * 签收任务
	 */
	@RequestMapping(value = "claim/{id}")
	public Result claim(@PathVariable("id") String taskId) {
		String userId = SecurityUtil.getUserId();
		taskService.claim(taskId, userId);
		Result result = Result.fail("任务已签收");
		result.setSuccess(true);
		return result;
	}

	/**
	 * 反签收任务
	 */
	@RequestMapping(value = "unclaim/{id}")
	public Result unclaim(@PathVariable("id") String taskId) {
		// 反签收条件过滤
		List<IdentityLink> links = taskService.getIdentityLinksForTask(taskId);
		Result result = Result.fail("该任务不允许反签收！");
		result.setSuccess(true);
		for (IdentityLink identityLink : links) {
			// 如果一个任务有相关的候选人、组就可以反签收
			if (StringUtils.equals(IdentityLinkType.CANDIDATE, identityLink.getType())) {
				taskService.claim(taskId, null);
				result.setMsg("任务已反签收");
				break;
			}
		}
		return result;
	}

	/**
	 * 任务委派
	 *
	 * @param taskId
	 * @param delegateUserId
	 */
	@RequestMapping("delegate/{taskId}")
	public Result delegate(@PathVariable("taskId") String taskId, @RequestBody JSONObject json) {
		String delegateUserId = json.getString("delegateUserId");
		taskService.delegateTask(taskId, delegateUserId);
		return Result.SUCCESS;
	}

	/**
	 * 读取用户任务的表单字段
	 */
	@RequestMapping(value = "getform/{taskId}")
	public Result readTaskForm(@PathVariable("taskId") String taskId) throws Exception {
		TaskFormData taskFormData = formService.getTaskFormData(taskId);
		Task task = null;

		Result result = Result.createResult(null);
		// 外置表单
		if (taskFormData != null && taskFormData.getFormKey() != null) {
			Object renderedTaskForm = formService.getRenderedTaskForm(taskId);
			task = taskService.createTaskQuery().taskId(taskId).singleResult();
			result.addMap("taskFormData", renderedTaskForm);
			result.addMap("hasFormKey", true);
		} else if (taskFormData != null) { // 动态表单
			result.addMap("taskFormData", taskFormData);
			task = taskFormData.getTask();
		} else { // 手动创建的任务（包括子任务）
			task = taskService.createTaskQuery().taskId(taskId).singleResult();
			result.addMap("manualTask", true);
		}
		result.addMap("task", task);

		// 读取任务参与人列表
		List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(taskId);
		result.addMap("identityLinksForTask", identityLinksForTask);

		// 读取所有人员
		List<User> users = identityService.createUserQuery().list();
		result.addMap("users", users);

		// 读取所有组
		List<Group> groups = identityService.createGroupQuery().list();
		result.addMap("groups", groups);

		// 读取子任务
		List<HistoricTaskInstance> subTasks = historyService.createHistoricTaskInstanceQuery().taskParentTaskId(taskId)
				.list();
		result.addMap("subTasks", subTasks);

		// 读取上级任务
		if (task != null && task.getParentTaskId() != null) {
			HistoricTaskInstance parentTask = historyService.createHistoricTaskInstanceQuery()
					.taskId(task.getParentTaskId()).singleResult();
			result.addMap("parentTask", parentTask);
		}

		// 读取附件
		List<Attachment> attachments = null;
		if (task.getTaskDefinitionKey() != null) {
			attachments = taskService.getTaskAttachments(taskId);
		} else {
			attachments = taskService.getProcessInstanceAttachments(task.getProcessInstanceId());
		}
		result.addMap("attachments", attachments);

		return result;
	}

}
